TanStack Query v5がリリースされてSuspense利用時の型定義の問題が解決されていたので試してみました
こんばんは、CX事業本部Delivery部サーバーサイドチームのmorimorikochanです。
表題の通り、TanStack Query v5 が2023年10月17日にリリースされました。それに合わせて、TypeScriptでSuspenseとTanStack Queryを併用した際にundefinedにならないはずの値がundefinedになってしまう型定義の問題が解決しているようです。公式ブログでも以下の部分で言及されています。
https://tanstack.com/blog/announcing-tanstack-query-v5#1st-class-suspense-support
この問題の改善を待っていた人は多いと思いますし僕もその一人です。今回は早速TanStack Query v5でのSuspense対応を試してみました。
undefinedにならないはずの値がundefinedになってしまう型定義の問題とは?
TanStack QueryのSuspenseサポートを有効にした状態では、useQuery()
から取得したデータの型は本来queryFn
の返り値の型のままであるはずなのですが、TanStack Query側でSuspense有効時の型定義が厳密にされておらず、undefined
になりえる型(queryFn
の返り値の型とundefined
とのユニオン型)として表現されていました。
Suspenseを利用することでコンポーネントに不要な型定義を持ち込まない様にできるにもかかわらず、この問題があるためにSuspenseのメリットを十分に受けれない状態になっていました。
詳細は以下のissueをご覧ください。
TanStack Query v5ではどうなった? どうやってSuspenseサポートを有効にするのか?
TanStack Query v5ではこの問題が解決されており、Suspenseサポートを有効にした状態でuseQuery()
経由で取得したデータの型は全てqueryFn
の返り値の型のままになるようになっています。
ただし1点注意しなければならないのが、v4までのようにuseQuery()
でデータフェッチすることはできません。v5でSuspense利用時はSuspense専用のhooksである useSuspenseQuery()
, useSuspenseInfiniteQuery()
, useSuspenseQueries()
を利用する必要があります
v5のuseQuery()
のドキュメントにはsuspense
オプションが存在していますがこれは誤りです。
せっかくなのでドキュメント修正のPRを出してみました
実際にSuspense書いてみた
useSuspenseQuery()
を利用してみましたが、確かに以前の問題は改善されており、以下コードのdata
変数の型はGithubRepository
のみになっていました
const GithubRepository = ({ repository }: { repository: string }) => { const { data } = useSuspenseQuery<GithubRepository>({ // ^? const data: GithubRepository queryKey: ["githubRepository"], queryFn: () => fetch(`https://api.github.com/repos/${repository}`).then((res) => res.json() ), }); return ( <div> <h2>GitHub Repository Detail</h2> <h3>{data.full_name}</h3> <ul> <li>id: {data.id}</li> <li>name: {data.name}</li> </ul> <img src={data.owner.avatar_url} /> </div> ); };
実際に書いたコードはこちらです
まとめ
- TanStack Query v5 では、Suspenseの型定義が改善されて、よりSuspenseが使いやすくなりました。
- ただし、v5では
useQuery()
が使えないのでv4からv5にアップデートする方は注意しましょう